package com.ruoyi.project.system.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.hash.Hashing;
import com.ruoyi.common.utils.ImageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.project.system.domain.dto.FacialVerification;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.faceid.v20180301.FaceidClient;
import com.tencentcloudapi.faceid.v20180301.models.CheckIdCardInformationRequest;
import com.tencentcloudapi.faceid.v20180301.models.CheckIdCardInformationResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.Charsets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.ruoyi.common.constant.CacheConstants.TXRLTK;

@Slf4j
@Service
public class TencentService {

    private static String secretId = "AKIDrriOtEPPE2f8QXTEoDRUM3Z3NXuBMQNF";

    private static String secretKey = "qZBh4YEuTtDScgaJ0Xt8ED0MVivDKG1a";

//  private static String baseImg = "http://82.156.68.252/prod-api/system/query/getAuthImg?filePath=";

//    private static String baseImg = "http://6fkmfq.natappfree.cc/system/query/getAuthImg?filePath=";

    private static String frontDomain = "http://chaxun.rongyica.com/result.html";

    @Autowired
    private RedisCache redisCache;

    public CheckIdCardInformationResponse imgAuth(byte[] imageBytes) throws TencentCloudSDKException {
        Credential cred = new Credential(secretId, secretKey);
        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("faceid.tencentcloudapi.com");
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        // 实例化要请求产品的client对象,clientProfile是可选的
        FaceidClient client = new FaceidClient(cred, "", clientProfile);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        CheckIdCardInformationRequest req = new CheckIdCardInformationRequest();
        req.setImageBase64(ImageUtils.convertToBase64(imageBytes));
        return client.CheckIdCardInformation(req);
    }

    public String sendIdentityInfoUserInfo(FacialVerification fv) throws Exception {
        // 1. 获取accessToken
        String accessToken = getAccessToken();
        if (accessToken == null) {
            throw new Exception("accessToken获取异常");
        }
        // 2. 获取signTicket
        String signTicket = getSignTicket(accessToken);
        if (signTicket == null) {
            throw new Exception("signTicket获取异常");
        }
        // 3. 合作方上送计算签名
        String userId = fv.getQueryId();
        String orderNo = fv.getOrderNo();
        List<String> list = new ArrayList<>();
        list.add("IDAwv84P");
        list.add(userId);
        list.add(orderNo);
        list.add("1.0.0");
//        list.add(fv.getName());
//        list.add(fv.getCardNo());
        list.add(signTicket);
        list.removeAll(Collections.singleton(null));
        java.util.Collections.sort(list);
        StringBuilder sb = new StringBuilder();
        for (String s : list) {
            sb.append(s);
        }
        String sign = Hashing.sha1().hashString(sb, Charsets.UTF_8).toString().toUpperCase();
        Map<String, String> param = new HashMap<>(16);
        param.put("appId", "IDAwv84P");
        param.put("orderNo", orderNo);
        param.put("name", fv.getName());
        param.put("idNo", fv.getCardNo());
        param.put("userId", userId);
        param.put("version", "1.0.0");
        param.put("sign", sign);
        param.put("nonce", orderNo);
        String backStr = HttpUtils.sendPost("https://kyc1.qcloud.com/api/server/getAdvFaceId?orderNo=" + orderNo, JSON.toJSONString(param), false, "application/json");
        // 4.获取腾讯signTicket
        JSONObject backJson = JSONObject.parseObject(backStr);
        if (!"0".equals(backJson.getString("code"))) {
            new Exception(backJson.getString("msg"));
        }
        String nonceTicketValue = redisCache.getCacheObject(TXRLTK + "nonceTicketTencent");
        if (StringUtils.isEmpty(nonceTicketValue)) {
            String nonceTickeStr = HttpUtils.sendGet("https://kyc1.qcloud.com/api/oauth2/api_ticket?appId=IDAwv84P&access_token=" + accessToken + "&type=NONCE&version=1.0.0&user_id=" + userId, null);
            JSONObject jsonMap = JSONObject.parseObject(nonceTickeStr);
            if (!"0".equals(jsonMap.getString("code"))) {
                log.error("获取腾讯nonceTicket信息错误", jsonMap);
                return null;
            }
            nonceTicketValue = jsonMap.getJSONArray("tickets").getJSONObject(0).getString("value");
            redisCache.setCacheObject(TXRLTK + "nonceTicketTencent", nonceTicketValue, 100, TimeUnit.SECONDS);
        }
        // 5. 启动H5
        String nonce_ = UUID.randomUUID().toString().replace("-", "");

        String optimalDomain = backJson.getJSONObject("result").getString("optimalDomain");
        String faceId = backJson.getJSONObject("result").getString("faceId");
        List<String> openList = new ArrayList<>();
        openList.add("1.0.0");
        openList.add(orderNo);
        openList.add("IDAwv84P");
        openList.add(faceId);
        openList.add(nonce_);
        openList.add(userId);
        openList.add(nonceTicketValue);
        openList.removeAll(Collections.singleton(null));
        java.util.Collections.sort(openList);
        StringBuilder sb_ = new StringBuilder();
        for (String s : openList) {
            sb_.append(s);
        }
        String sign_ = Hashing.sha1().hashString(sb_, Charsets.UTF_8).toString().toUpperCase();
        return "https://" + optimalDomain + "/api/web/login?appId=IDAwv84P&version=1.0.0&nonce=" + nonce_ + "&orderNo=" + orderNo + "&faceId=" + faceId +
                "&url=" + URLEncoder.encode(frontDomain, "UTF-8") + "&userId=" + userId + "&sign=" + sign_ + "&redirectType=1&from=browser&resultType=1";
    }

    public JSONObject getFaceAuthResult(String orderNo) throws Exception {
        // 1. 获取accessToken
        String accessToken = getAccessToken();
        if (accessToken == null) {
            throw new Exception("accessToken获取异常");
        }
        // 2. 获取signTicket
        String signTicket = getSignTicket(accessToken);
        if (signTicket == null) {
            throw new Exception("signTicket获取异常");
        }
        // 3. 合作方上送计算签名
        String nonce_ = UUID.randomUUID().toString().replace("-", "");
        List<String> list = new ArrayList<>();
        list.add("IDAwv84P");
        list.add(orderNo);
        list.add("1.0.0");
        list.add(signTicket);
        list.add(nonce_);
        list.removeAll(Collections.singleton(null));
        java.util.Collections.sort(list);
        StringBuilder sb = new StringBuilder();
        for (String s : list) {
            sb.append(s);
        }
        String sign_ = Hashing.sha1().hashString(sb, Charsets.UTF_8).toString().toUpperCase();
        Map<String, String> param_ = new HashMap<>(16);
        param_.put("appId", "IDAwv84P");
        param_.put("version", "1.0.0");
        param_.put("nonce", nonce_);
        param_.put("orderNo", orderNo);
        param_.put("sign", sign_);
        param_.put("getFile", "2");
        String url = "https://kyc1.qcloud.com/api/v2/base/queryfacerecord?orderNo=" + orderNo;
        String jsonStr_ = HttpUtils.sendPost(url, JSON.toJSONString(param_), false, "application/json");
        return JSONObject.parseObject(jsonStr_);
    }

    public String getAccessToken() {
        String accessToken = redisCache.getCacheObject(TXRLTK + "accessTokenTencent");
        if (StringUtils.isEmpty(accessToken)) {
            String jsonStr = HttpUtils.sendGet("https://kyc1.qcloud.com/api/oauth2/access_token?appId=IDAwv84P&secret=YQywZZCApFYjRfXWZq0zFHbfGzusDTUzYpQocH3abJQD5VrWJfyGT8XPCTYA1Ep6&grant_type=client_credential&version=1.0.0", null);
            log.warn("accessToken返回报文", jsonStr);
            JSONObject jsonMap = JSONObject.parseObject(jsonStr);
            if (!"0".equals(jsonMap.get("code"))) {
                return null;
            }
            accessToken = jsonMap.getString("access_token");
            // 过期时间 默认7200L  设置6800L提前重新获取
            redisCache.setCacheObject(TXRLTK + "accessTokenTencent", accessToken, 6800, TimeUnit.SECONDS);
        }
        return accessToken;
    }

    public String getSignTicket(String accessToken) {
        String signTicket = redisCache.getCacheObject(TXRLTK + "signTicketTencent");
        if (StringUtils.isEmpty(signTicket)) {
            String jsonStr = HttpUtils.sendGet("https://kyc1.qcloud.com/api/oauth2/api_ticket?appId=IDAwv84P&access_token=" + accessToken + "&type=SIGN&version=1.0.0", null);
            JSONObject jsonMap = JSONObject.parseObject(jsonStr);
            log.warn("signTicket返回报文", jsonMap);
            if (!"0".equals(jsonMap.getString("code"))) {
                return null;
            }
            signTicket = jsonMap.getJSONArray("tickets").getJSONObject(0).getString("value");
            // 过期时间 默认3600L  设置3200L提前重新获取
            redisCache.setCacheObject(TXRLTK + "signTicketTencent", signTicket, 3000, TimeUnit.SECONDS);
        }
        return signTicket;
    }
}
